package com.isoftstone.demo.global.service.impl;

import com.isoftstone.demo.global.constant.DemoStatus;
import com.isoftstone.demo.global.dao.DemoDao;
import com.isoftstone.demo.global.entity.Demo;
import com.isoftstone.demo.global.service.DemoService;
import com.isoftstone.services.base.entity.User;
import com.isoftstone.services.data.service.impl.BaseJpaService;
import com.isoftstone.services.user.service.UserService;
import org.springframework.context.annotation.Lazy;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.condition.ConditionSpecification;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.persistence.criteria.Path;
import javax.persistence.criteria.Predicate;
import java.util.Date;
import java.util.List;
import java.util.Objects;

/**
 * Demo服务
 *
 * @author TianGanLin
 * @version 1.0.0, 2017/10/23
 * @since 1.8
 */
@Service
public class DemoServiceImpl extends BaseJpaService<Demo, Integer, DemoDao> implements DemoService {

    @Resource
    @Lazy
    private UserService userService;

    @Override
    public Demo add(Demo model) {
        Demo twin = twin(model);
        if (Objects.nonNull(twin)) // 如果有相似的巡查, 则更新
            return super.patch(model, twin);
        initDemo(model);
        return dao().save(model);
    }

    @Override
    public Demo patch(Demo demo) {
        Demo target = pullOne(demo.getId());
        return super.patch(demo, target);
    }

    @Override
    public Demo get(Integer id) {
        return dao().findOne(((root, query, cb) -> cb.equal(root.get("id"), id)));
    }

    @Override
    public Page<Demo> paging(Demo demo, Pageable pageable) {
        return dao().findAll(demo, specification(demo), pageable);
    }

    /**
     * 初始化巡查
     */
    private void initDemo(Demo demo) {
        if (Objects.isNull(demo.getCreator()))
            demo.setCreator(getCurrentUser());
        if (Objects.isNull(demo.getStatus()))
            demo.setStatus(DemoStatus.CREATE);
        if (Objects.isNull(demo.getDate()))
            demo.setDate(new Date());
    }

    /**
     * 获取相似的巡查
     *
     * @param model 参数
     * @return 实体
     */
    private Demo twin(Demo model) {
        ConditionSpecification<Demo> specification = (
                (root, query, cb, jc) -> jc.clauseAnd(jc.equalsInclude("company", "address", "category")));
        List<Demo> demos = dao().findAll(model, specification);
        if (demos.size() > 0) return demos.get(0);
        return null;
    }

    /**
     * 查询条件
     */
    private ConditionSpecification<Demo> specification(Demo demo) {
        return (root, query, cb, jc) -> {
            // 按主键、状态匹配
            Predicate[] equalsInclude = jc.equalsInclude("id", "status");
            // 按巡查创建人、地点、巡查单位搜索
            Predicate[] likesInclude = jc.likesInclude("address", "company");
            User creator = demo.getCreator();
            if (Objects.nonNull(creator)) {
                Path<User> creatorPath = root.get("creator");
                if (Objects.nonNull(creator.getDepartmentId())) // 按所属机构匹配
                    jc.clauseAnd(cb.equal(creatorPath.get("departmentId"), creator.getDepartmentId()));
                if (Objects.nonNull(creator.getAccount())) // 按账号筛选
                    jc.clauseAnd(cb.like(creatorPath.get("account"), creator.getAccount() + "%"));
            }
            Predicate date = jc.between("date");
            // 将条件注入CriteriaQuery
            jc.clauseAnd(jc.mergeAnd(equalsInclude), jc.mergeAnd(likesInclude), date);
        };
    }
}
